/*  
	Project: 	Sound Loader Helper Classes
				Use to load a sound in memory.
	Copyright (C) 2009, Jerome Maurey-Delaunay, all rights reserved.
	contact jerome(at)wemakedotcoms.com
	
	
	Legal crap I see in most open source project (and makes this look official):
	Redistribution and use in source and binary forms, with or without modification,
	are permitted provided that the following conditions are met:
	
	  * Redistribution's of source code must retain the above copyright notice,
		this list of conditions and the following disclaimer.
	
	  * Redistribution's in binary form must reproduce the above copyright notice,
		this list of conditions and the following disclaimer in the documentation
		and/or other materials provided with the distribution.
	
	This software is provided by the copyright holders and contributors "as is" and
	any express or implied warranties, including, but not limited to, the implied
	warranties of merchantability and fitness for a particular purpose are disclaimed.
	In no event shall I or contributors be liable for any direct,
	indirect, incidental, special, exemplary, or consequential damages
	(including, but not limited to, procurement of substitute goods or services;
	loss of use, data, or profits; or business interruption) however caused
	and on any theory of liability, whether in contract, strict liability,
	or tort (including negligence or otherwise) arising in any way out of
	the use of this software, even if advised of the possibility of such damage.
*/


package com.wemakedotcoms.audio
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundLoaderContext;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;
	
	
	public class SoundLoader extends EventDispatcher
	{
		
		/* Events for Sound*/
		public static const ACTIVATE:String			= Event.ACTIVATE;
		public static const COMPLETE:String 		= Event.COMPLETE;
		public static const DEACTIVATE:String		= Event.DEACTIVATE;
		public static const ID3:String				= Event.ID3;
		public static const OPEN:String				= Event.OPEN;		
		public static const IO_ERROR:String 		= IOErrorEvent.IO_ERROR;
		public static const PROGRESS:String 		= ProgressEvent.PROGRESS;
		
		/* Events for SoundChannel */
		public static const SOUND_COMPLETE:String	= Event.SOUND_COMPLETE;
		public static const SOUND_ACTIVATE:String	= Event.ACTIVATE;
		public static const SOUND_DEACTIVATE:String	= Event.DEACTIVATE;
		
		
		/* some state variables I use. */	 
		public var isPlaying:Boolean = false;
		public var isLoading:Boolean = false;
		public var isLoaded:Boolean = false;
		
		/* Sound variables */
		public var sound:Sound = new Sound();
		public var soundChannel:SoundChannel = new SoundChannel();
		
		public function SoundLoader(target:IEventDispatcher=null)
		{
			super(target);
			
			initEvents();
		}
		
		/* Load Sound */
		public function loadSound(url:String):void
		{
			this.sound.load(new URLRequest(url));
			this.isLoading = true;
		}
		
		/* Plays sound Sound */
		public function play(startTime:Number = 0, loops:int = 0, sndTransform:SoundTransform = null):void
		{
			if(isLoaded && !isPlaying){
				this.soundChannel = this.sound.play(startTime, loops, sndTransform);
				this.isPlaying = true;
			}
		}
		
		/* Stops Sound */
		public function stop():void
		{
			if(isPlaying){			
				this.soundChannel.stop();
				this.isPlaying = false;
			}
		}
		
		
		
		/* Init internal Events */
		public function initEvents():void
		{
			// Sound
			sound.addEventListener(Event.ACTIVATE,					onSoundActive, 				false, 0, true);
			sound.addEventListener(Event.COMPLETE,					onSoundComplete, 			false, 0, true);
			sound.addEventListener(Event.DEACTIVATE,				onSoundDeactivate, 			false, 0, true);
			sound.addEventListener(Event.ID3, 						onSoundID3, 				false, 0, true);
			sound.addEventListener(Event.OPEN, 						onSoundSoundOpen, 			false, 0, true);
			sound.addEventListener(IOErrorEvent.IO_ERROR, 			onSoundIOError, 			false, 0, true);
			sound.addEventListener(ProgressEvent.PROGRESS, 			onSoundProgress, 			false, 0, true);
			// SoundChannel
			soundChannel.addEventListener(Event.SOUND_COMPLETE, 	onSoundChannelComplete, 	false, 0, true);
			soundChannel.addEventListener(Event.ACTIVATE,			onSoundChannelActivate, 	false, 0, true);
			soundChannel.addEventListener(Event.DEACTIVATE,			onSoundChannelDeactivate, 	false, 0, true);
		}
		
		
		/* Event Handlers */		
		
		public function onSoundActive(e:Event):void
		{
			 dispatchEvent(e);
		}
		
		public function onSoundComplete(e:Event):void
		{
			this.isLoading = false;
			this.isLoaded = true;
			
			dispatchEvent(e);
		}
		
		public function onSoundDeactivate(e:Event):void
		{
			 dispatchEvent(e);
		}
		
		public function onSoundID3(e:Event):void
		{
			 dispatchEvent(e);
		}
		
		public function onSoundSoundOpen(e:Event):void
		{
			 dispatchEvent(e);
		}
		
		public function onSoundIOError(e:IOErrorEvent):void
		{
			dispatchEvent(e);
		}
		
		public function onSoundProgress(e:ProgressEvent):void
		{
			dispatchEvent(e);
		}
		
		public function onSoundChannelComplete(e:Event):void
		{
			this.isPlaying = false;
			
			dispatchEvent(e);
		}
		
		public function onSoundChannelActivate(e:Event):void
		{
			dispatchEvent(e);
		}
		
		public function onSoundChannelDeactivate(e:Event):void
		{
			dispatchEvent(e);
		}
	}
}